#ifndef _DEVICES_MOTOR_H_
#define _DEVICES_MOTOR_H_


#define MOTOR_OUTPUT_CHANNEL_LEFT_MOVE  0x01
#define MOTOR_OUTPUT_CHANNEL_LEFT_BACK  0x02
#define MOTOR_OUTPUT_CHANNEL_RIGHT_MOVE 0x04
#define MOTOR_OUTPUT_CHANNEL_RIGHT_BACK 0x08

#define MOTOR_OUTPUT_CHANNEL_MOVE  (MOTOR_OUTPUT_CHANNEL_LEFT_MOVE  | MOTOR_OUTPUT_CHANNEL_RIGHT_MOVE)
#define MOTOR_OUTPUT_CHANNEL_BACK  (MOTOR_OUTPUT_CHANNEL_LEFT_BACK  | MOTOR_OUTPUT_CHANNEL_RIGHT_BACK)
#define MOTOR_OUTPUT_CHANNEL_LEFT  (MOTOR_OUTPUT_CHANNEL_LEFT_MOVE  | MOTOR_OUTPUT_CHANNEL_LEFT_BACK)
#define MOTOR_OUTPUT_CHANNEL_RIGHT (MOTOR_OUTPUT_CHANNEL_RIGHT_MOVE | MOTOR_OUTPUT_CHANNEL_RIGHT_BACK)
#define MOTOR_OUTPUT_CHANNEL_ALL        0xFF


#define MOTOR_PWM_LEFT_MOVE_RCC_GPIO_CLK  RCU_GPIOA
#define MOTOR_PWM_LEFT_MOVE_GPIO_Port     GPIOA
#define MOTOR_PWM_LEFT_MOVE_Pin           GPIO_PIN_6

#define MOTOR_PWM_LEFT_BACK_RCC_GPIO_CLK  RCU_GPIOC
#define MOTOR_PWM_LEFT_BACK_GPIO_Port     GPIOC
#define MOTOR_PWM_LEFT_BACK_Pin           GPIO_PIN_4

#define MOTOR_PWM_RIGHT_MOVE_RCC_GPIO_CLK RCU_GPIOA
#define MOTOR_PWM_RIGHT_MOVE_GPIO_Port    GPIOA
#define MOTOR_PWM_RIGHT_MOVE_Pin          GPIO_PIN_7

#define MOTOR_PWM_RIGHT_BACK_RCC_GPIO_CLK RCU_GPIOC
#define MOTOR_PWM_RIGHT_BACK_GPIO_Port    GPIOC
#define MOTOR_PWM_RIGHT_BACK_Pin          GPIO_PIN_5

#define MOTOR_ENCODE_LEFT_RCC_GPIO_CLK    RCU_GPIOB
#define MOTOR_ENCODE_LEFT_GPIO_Port       GPIOB
#define MOTOR_ENCODE_LEFT_Pin             GPIO_PIN_4

#define MOTOR_ENCODE_RIGHT_RCC_GPIO_CLK   RCU_GPIOC
#define MOTOR_ENCODE_RIGHT_GPIO_Port      GPIOC
#define MOTOR_ENCODE_RIGHT_Pin            GPIO_PIN_7


#define MOTOR_ENABLE_ALL()  (void)(0)
#define MOTOR_DISABLE_ALL() do{ TIMER_CH0CV(TIMER2) = 0; TIMER_CH1CV(TIMER2) = 0; TIMER_CH2CV(TIMER2) = 0; TIMER_CH3CV(TIMER2) = 0; }while(0)




#define MOTOR_DIRECTION_MOVE (1)
#define MOTOR_DIRECTION_BACK (-1)




#define MOTOR_PWM_PRESCALER 9
#define MOTOR_PWM_FREQUENCY 210
#define MOTOR_PWM_PERIOD    (SystemCoreClock / MOTOR_PWM_PRESCALER / MOTOR_PWM_FREQUENCY)

#define MOTOR_ENCODE_UPDATE_FREQUENCY 1000





typedef struct{
    int8_t state;
    int32_t cntNow;
    int16_t cntOverflow;
    uint16_t encodeLast;
    int32_t encodeSum;

    float speedSet;
    float speedGet;
    float currentGet;

    int8_t direction;
}MotorType;

typedef struct{
    MotorType left;
    MotorType right;
}MotorInfoType;




extern MotorInfoType g_typeMotorInfo;







void vMotorInit(void);
void vMotorOutputInit(void);
void vMotorEncodeInit(void);

void vMoterUpdateSpeed(void);
float fMotorGetSpeed(uint8_t ucChannel);
int8_t cMotorSetSpeed(uint8_t ucChannel, float fSpeed);

float fMotorGetCurrent(uint8_t ucChannel);

int8_t cMotorInfoUpdate(void);
MotorInfoType *ptypeMotorGetInfo(void);



#endif
